/**
 * Copyright &copy; 2012-2013 <a href="https://github.com/thinkgem/jeesite">JeeSite</a> All rights reserved.
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License");
 */
package com.cn.ant.modules.sys.utils;

import com.cn.ant.common.service.BaseService;
import com.cn.ant.common.utils.SpringContextHolder;
import com.cn.ant.modules.sys.dao.*;
import com.cn.ant.modules.sys.entity.*;
import com.cn.ant.modules.sys.security.SystemAuthorizingRealm.Principal;
import com.google.common.collect.Maps;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.UnavailableSecurityManagerException;
import org.apache.shiro.session.InvalidSessionException;
import org.apache.shiro.subject.Subject;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 用户工具类
 *
 * @author ThinkGem
 * @version 2013-5-29
 */
public class UserUtils extends BaseService {

    private static UserMapper userMapper = SpringContextHolder.getBean(UserMapper.class);
    private static RoleMapper roleMapper = SpringContextHolder.getBean(RoleMapper.class);
    private static MenuMapper menuMapper = SpringContextHolder.getBean(MenuMapper.class);
    private static AreaMapper areaMapper = SpringContextHolder.getBean(AreaMapper.class);
    private static OfficeMapper officeMapper = SpringContextHolder.getBean(OfficeMapper.class);

    public static final String CACHE_USER = "user";
    public static final String CACHE_ROLE_LIST = "roleList";
    public static final String CACHE_MENU_LIST = "menuList";
    public static final String CACHE_AREA_LIST = "areaList";
    public static final String CACHE_PROVINCE_LIST = "provinceList";
    public static final String CACHE_OFFICE_LIST = "officeList";

    public static User getUser() {
        User user = (User) getCache(CACHE_USER);
        if (user == null) {
            try {
                Subject subject = SecurityUtils.getSubject();
                Principal principal = (Principal) subject.getPrincipal();
                if (principal != null) {
                    user = userMapper.get(principal.getId());
//					Hibernate.initialize(user.getRoleList());
                    putCache(CACHE_USER, user);
                }
            } catch (UnavailableSecurityManagerException e) {

            } catch (InvalidSessionException e) {

            }
        }
        if (user == null) {
            user = new User();
            try {
                SecurityUtils.getSubject().logout();
            } catch (UnavailableSecurityManagerException e) {

            } catch (InvalidSessionException e) {

            }
        }
        return user;
    }

    public static User getUser(boolean isRefresh) {
        if (isRefresh) {
            removeCache(CACHE_USER);
        }
        return getUser();
    }

    /**
     * 获取当前登录者对象
     */
    public static Principal getPrincipal() {
        try {
            Subject subject = SecurityUtils.getSubject();
            Principal principal = (Principal) subject.getPrincipal();
            if (principal != null) {
                return principal;
            }
        } catch (UnavailableSecurityManagerException e) {

        } catch (InvalidSessionException e) {

        }
        return null;
    }

    public static List<Role> getRoleList() {
        @SuppressWarnings("unchecked")
        List<Role> list = (List<Role>) getCache(CACHE_ROLE_LIST);
        if (list == null) {
            User user = getUser();
            Map<String, String> params = new HashMap<String, String>();
            params.put("userId", user.getId());
            params.put("userscope", "yes");
            params.put("isadmin", user.isAdmin() + "");
            list = roleMapper.find(params);
            putCache(CACHE_ROLE_LIST, list);
        }
        return list;
    }

    public static List<Menu> getMenuList() {
        @SuppressWarnings("unchecked")
        List<Menu> menuList = (List<Menu>) getCache(CACHE_MENU_LIST);
        if (menuList == null || menuList.size() == 0) {
            User user = getUser();
            if (user.isAdmin()) {
                menuList = menuMapper.findAllList();
            } else {
                menuList = menuMapper.findByUserId(user.getId());
            }
            putCache(CACHE_MENU_LIST, menuList);
        }
        return menuList;
    }

    public static List<Area> getAreaList() {
        @SuppressWarnings("unchecked")
        List<Area> areaList = (List<Area>) getCache(CACHE_AREA_LIST);
        if (areaList == null) {
            areaList = areaMapper.findAllList(null);
            putCache(CACHE_AREA_LIST, areaList);
        }
        return areaList;
    }

    /**
     * 获取省份信息
     * @return
     */
    public static List<Area> getProvinceList(){
        List<Area> areaList = (List<Area>) getCache(CACHE_AREA_LIST);
        if (areaList == null) {
            areaList = areaMapper.findAllList(null);
            putCache(CACHE_AREA_LIST, areaList);
        }
        List<Area> provinceList = (List<Area>) getCache(CACHE_PROVINCE_LIST);
        if (provinceList == null) {
            Area area = null;
            provinceList = new ArrayList<>();
            for (int i = 0; i < areaList.size(); i++) {
                area = areaList.get(i);
                if (area.getType().equals("2")) {
                    provinceList.add(area);
                }
            }
            putCache(CACHE_PROVINCE_LIST, provinceList);
        }
        return provinceList;
    }

    public static List<Office> getOfficeList() {
        @SuppressWarnings("unchecked")
        List<Office> officeList = (List<Office>) getCache(CACHE_OFFICE_LIST);
        if (officeList == null) {
            officeList = officeMapper.findAllList();// 查询所有的菜单
            putCache(CACHE_OFFICE_LIST, officeList);
        }
        return officeList;
    }

    // ============== User Cache ==============

    public static Object getCache(String key) {
        return getCache(key, null);
    }

    public static Object getCache(String key, Object defaultValue) {
        Object obj = getCacheMap().get(key);
        return obj == null ? defaultValue : obj;
    }

    public static void putCache(String key, Object value) {
        getCacheMap().put(key, value);
    }

    public static void removeCache(String key) {
        getCacheMap().remove(key);
    }

    public static Map<String, Object> getCacheMap() {
        Map<String, Object> map = Maps.newHashMap();
        try {
            Subject subject = SecurityUtils.getSubject();
            Principal principal = (Principal) subject.getPrincipal();
            return principal != null ? principal.getCacheMap() : map;
        } catch (UnavailableSecurityManagerException e) {

        } catch (InvalidSessionException e) {

        }
        return map;
    }

}
